package com.lz.ub

import android.app.PendingIntent
import android.app.Service
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.hardware.usb.UsbDevice
import android.hardware.usb.UsbManager
import android.os.Build
import android.os.IBinder
import java.util.*

/**
 * @author You
 * 后台服务管理类, 会自动管理插拔状态, 在插拔时会自动重置设备
 */
@Suppress("DEPRECATION")
class UBCService : Service() {

    companion object {

        private const val ACTION_USB_PERMISSION = "com.lz.ub.UBCService_USB_PERMISSION"

        fun start(context: Context) {
            context.startService(Intent(context, UBCService::class.java))
        }
    }

    private val usbManager by lazy { getSystemService(Context.USB_SERVICE) as UsbManager }

    //USB权限和插拔广播
    private val usbReceiver by lazy { USBBroadcastReceiver() }

    //等待请示权限的设备
    private val pendingPermissionDevices = LinkedList<UsbDevice>()

    override fun onBind(intent: Intent?): IBinder? = null

    override fun onCreate() {
        registerReceiver(usbReceiver, IntentFilter().apply {
            addAction(ACTION_USB_PERMISSION)
            addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED)
            addAction(UsbManager.ACTION_USB_DEVICE_DETACHED)
        })
    }

    override fun onDestroy() {
        super.onDestroy()
        unregisterReceiver(usbReceiver)
    }

    override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
        val usbDevices = usbManager.deviceList
        if (usbDevices.isEmpty()) {
            UBCConfig.deviceEmpty()
        } else {
            for (entry in usbDevices.entries) {
                if (UBCConfig.isSupport(entry.value)) {
                    if (usbManager.hasPermission(entry.value)) {
                        UBCConfig.addUsbDevice(entry.value)
                    } else {
                        pendingPermissionDevices.add(entry.value)
                    }
                }
            }
            requestPermission()
        }
        return START_NOT_STICKY
    }

    private fun requestPermission() {
        val device = pendingPermissionDevices.pollFirst() ?: return
        usbManager.requestPermission(
            device, PendingIntent.getBroadcast(
                this, 0, Intent(ACTION_USB_PERMISSION),
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) PendingIntent.FLAG_MUTABLE else 0
            )
        )
    }

    inner class USBBroadcastReceiver : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
            when (intent.action) {
                UsbManager.ACTION_USB_DEVICE_ATTACHED -> {
                    val device = intent.extras?.getParcelable<UsbDevice>(UsbManager.EXTRA_DEVICE) ?: return
                    if (UBCConfig.isSupport(device)) {
                        if (usbManager.hasPermission(device)) {
                            UBCConfig.addUsbDevice(device)
                        } else {
                            pendingPermissionDevices.add(device)
                            requestPermission()
                        }
                        UBCConfig.deviceState(device, UBCConfig.DEVICE_ATTACHED)
                    }
                }
                UsbManager.ACTION_USB_DEVICE_DETACHED -> {
                    val device = intent.extras?.getParcelable<UsbDevice>(UsbManager.EXTRA_DEVICE) ?: return
                    pendingPermissionDevices.remove(device)
                    UBCConfig.removeUsbDevice(device)
                    UBCConfig.deviceState(device, UBCConfig.DEVICE_DETACHED)
                }
                ACTION_USB_PERMISSION -> {
                    val device = intent.extras?.getParcelable<UsbDevice>(UsbManager.EXTRA_DEVICE) ?: return
                    if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
                        UBCConfig.addUsbDevice(device)
                        UBCConfig.devicePermission(device, UBCConfig.DEVICE_PERMISSION_GRANTED)
                        requestPermission()
                    } else {
                        UBCConfig.devicePermission(device, UBCConfig.DEVICE_PERMISSION_REFUSE)
                    }
                }
            }
        }
    }
}